package com.wx.nbregisterserver.server;


import com.wx.nbregisterserver.context.RegistMesgContext;
import com.wx.nbregisterserver.context.RegisterMapContext;
import com.wx.nbregisterserver.entity.Mesg4Moniter;
import com.wx.nbregisterserver.entity.NBServerConfigProperties;



import com.wx.nbregisterserver.entity.ServerInfomation;
import org.nd4j.shade.jackson.core.JsonProcessingException;
import org.nd4j.shade.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


import java.io.File;
import java.io.FileOutputStream;

import java.io.ObjectOutputStream;
import java.sql.*;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Date;


@RestController
public class RegisterServer {

    /**
     * 接收需要注册的服务信息
     */
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RegistMesgContext registMesgContext;



    /**
     * 把ip地址与端口注册到注册中心
     * @param properties  客户端注册信息
     * @throws SQLException jdbc异常
     * @throws JsonProcessingException
     */

    @RequestMapping("/register/story")
    public String getRegisterMesg( @RequestBody NBServerConfigProperties properties) {

        HashMap<String, ServerInfomation> registerMap = RegisterMapContext.getRegisterMap();
        ObjectMapper mapper = new ObjectMapper();
        String json = null;
        try {
            json = mapper.writeValueAsString(properties);
            String port = properties.getPort();
            String host = properties.getHost();
            String serverName = properties.getServerName();

            // 注册信息存储到ServerInfomation实体类中
            ServerInfomation infomation = new ServerInfomation();
            infomation.setIp(host);
            infomation.setPort(Integer.valueOf(port));
            infomation.setRegistTime(new Date());
            infomation.setStatus(true);
            infomation.setServerName(serverName);
            // 把实体类存储到集合中

            registerMap.put(serverName,infomation);
            // 判断是否需要序列化到本地文件中
            boolean storage2File = properties.isStorage2File();
            if (storage2File){
                // 判断是否配置文件夹
                String filePath = properties.getFilePath();
                File file = new File(filePath);
                // 判断是否存在
                if(!file.exists()){
                    // 不存在就创建文件夹
                    file.mkdirs();
                }
                // 判断是否是一个文件夹
                if(file.isFile()){
                    throw new RuntimeException("请确定存储注册信息的路径是否是一个文件夹");
                }
                File storyFile = new File(file, properties.getServerName()+"registerMesg.txt");
                // 把注册信息序列化到本地文件中

                    ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(storyFile));
                    objectOutputStream.writeObject(properties);



            }
            // 判断是否把信息注册到数据库中
            boolean storage2Redis = properties.isStorage2Redis();
            if(storage2Redis){
                redisTemplate.opsForValue().set(serverName,json);
            }
            // 判断是否把信息存储到数据库中
            boolean storage2Mysql = properties.isStorage2Mysql();
            if(storage2Mysql){
                //注册驱动

                    Class.forName("com.mysql.jdbc.Driver");

                String mysqlHost = properties.getMysqlHost();
                String mysqlPassword = properties.getMysqlPassword();
                String mysqlUsername = properties.getMysqlUsername();
                // 连接数据库
                // 注册驱动
                try {
                    Class.forName("com.mysql.jdbc.Driver");
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                // 连接数据库
                Connection connection = null;

                    String url="jdbc:mysql://"+mysqlHost;

                    connection = DriverManager.getConnection(url, mysqlUsername, mysqlPassword);

                // 创建执行sql句柄对象
                Statement statement = null;

                    statement = connection.createStatement();

                // 创建数据库
                String sql="CREATE DATABASE IF NOT EXISTS register";

                    statement.execute(sql);

                // 使用这个数据库
                statement.execute("use register ");
                // 创建表
                statement.execute("CREATE TABLE  registerMesg(id INT PRIMARY KEY AUTO_INCREMENT, serverName VARCHAR(100),ipAndHost TEXT )");
                // 把注册信息存储到数据库中
                String insertSql="INSERT INTO registerMesg VALUES(null,?,?)";
                PreparedStatement preparedStatement = connection.prepareStatement(insertSql);
                preparedStatement.setString(1,serverName);

                preparedStatement.setString(2,json);
                // 执行插入
                preparedStatement.executeUpdate();
                // 关闭连接
                if(statement!=null){

                    statement.close();
                }
                if(preparedStatement!=null){

                    preparedStatement.close();
                }
                if(connection!=null){

                    connection.close();
                }

        }
        } catch (Exception throwables) {
            return "false";

        }


        System.out.println(properties);

        // 把注册信息保存到上下文中
        registMesgContext.putMesg(registerMap);
        //

        return "success";
    }
    /**
     * 从注册中心获取注册地址
     */
    @RequestMapping("/register/getInfo/{serverName}")
    public ServerInfomation getIpAndPort(@PathVariable("serverName") String serverName){
        if(serverName!=null){
            HashMap<String, ServerInfomation> mesg = registMesgContext.getMesg();

            ServerInfomation serverInfomation = mesg.get(serverName);
            return serverInfomation;
        }else {
            throw new RuntimeException("获取服务定位信息失败");
        }
    }
    /**
     * 消费端心跳回应
     */
    @RequestMapping("/register/heartBeat")
    public Boolean getHeartBeat(){
        return true;
    }


    /**
     * 获得所有的注册信息
     */
    public  HashMap<String, ServerInfomation> getAllRegisterMesg(){
        HashMap<String, ServerInfomation> registerMap = RegisterMapContext.getRegisterMap();
        return registerMap;
    }
    // register/getShowData
    @RequestMapping("/register/getShowData")
    public   List   getShowData(){
        ArrayList<Mesg4Moniter> list = new ArrayList<>();
        HashMap<String, ServerInfomation> mesg = registMesgContext.getMesg();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (Map.Entry<String, ServerInfomation> entry : mesg.entrySet()) {
            ServerInfomation value = entry.getValue();
            Mesg4Moniter moniter = new Mesg4Moniter();
            moniter.setIp(value.getIp());
            moniter.setPort(value.getPort()+"");
            String format = sdf.format(value.getRegistTime());
            moniter.setRegistTime(format);
            moniter.setServerName(value.getServerName());
            if(value.getStatus()){
                moniter.setStatus("可用");
            }else {
                moniter.setStatus("不可用");
            }
            list.add(moniter);
        }
        return list;
    }

}
